/* mutil.h
**
** Copyright (c) 2007, Meadhbh S. Hamrick
** All rights reserved.
** 
** Redistribution  and  use  in  source  and  binary  forms,  with  or  without
** modification, are permitted provided that the following conditions are met:
** 
**  * Redistributions of  source code must  retain the above  copyright notice,
**    this list of conditions and the following disclaimer.
** 
**  * Redistributions in binary form must reproduce the above copyright notice,
**    this list of conditions and the following disclaimer in the documentation
**    and/or other materials provided with the distribution.
** 
**  * Neither the  name of  Project Meadhbh  nor the names of  its contributors
**    may be used  to endorse  or promote  products derived from this  software
**    without specific prior written permission.
** 
** THIS SOFTWARE IS PROVIDED BY  THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY  EXPRESS OR IMPLIED WARRANTIES,  INCLUDING, BUT NOT  LIMITED TO, THE
** IMPLIED WARRANTIES  OF MERCHANTABILITY AND FITNESS FOR  A PARTICULAR PURPOSE
** ARE DISCLAIMED.  IN NO  EVENT SHALL THE  COPYRIGHT OWNER OR  CONTRIBUTORS BE
** LIABLE  FOR  ANY  DIRECT,   INDIRECT,  INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR
** CONSEQUENTIAL  DAMAGES  (INCLUDING,  BUT  NOT  LIMITED  TO,  PROCUREMENT  OF
** SUBSTITUTE GOODS  OR SERVICES;  LOSS OF USE,  DATA, OR PROFITS;  OR BUSINESS
** INTERRUPTION)  HOWEVER CAUSED  AND ON  ANY THEORY  OF LIABILITY,  WHETHER IN
** CONTRACT,  STRICT LIABILITY,  OR  TORT (INCLUDING  NEGLIGENCE OR  OTHERWISE)
** ARISING IN ANY WAY  OUT OF THE USE OF THIS SOFTWARE,  EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
** 
** $Id: mutil.h 49 2007-08-31 07:52:32Z msh.mobile $
*/

/* Originally  part of  the DangerThink  project source  base,  this file
** includes  a number of  other standard  system includes  like stddef.h,
** stdint.h, config.h,  etc. We use  the autoconf tools  to automatically
** generate makefiles  and the config.h file. In  theory, you're supposed
** to check various macro definitions  in each .c file before you include
** headers, but  this gets a  little tedious. So  we moved all  that into
** this header file.  So if you look at the various  .c files, you'll see
** that   they   all  include   this   file,   and   then  they   include
** package-specific headers.
*/

/* Macro Definitions */
#ifndef _H_MUTIL
#define _H_MUTIL

/* File Inclusions */
#include <stdio.h>

/* Read the config file generated by the ./configure script */
#ifdef HAVE_CONFIG_H
#include "config.h"
#else
#error __FILE__ requires a valid config.h header file.
#endif /* HAVE_CONFIG_H */

/* force the use of the library version of malloc */
#ifdef malloc
#undef malloc
#endif

/* check for networking goodiness */
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#else
#ifdef HAVE_WINSOCK2_H
#include <winsock2.h>
#else
#error __FILE__ requires the arpa/inet.h header file.
#endif /* HAVE_WINSOCK2_H */
#endif /* HAVE_ARPA_INET_H */

/* check for strings, memcpy() is used everywhere. strlen() and memcmp() are
** used extensively in tests.
*/
#ifdef HAVE_STRING_H
#include <string.h>
#else
#ifdef HAVE_STRINGS_H
#include <strings.h>
#else
#error __FILE__ requires either a string.h or strings.h head file.
#endif /* HAVE_STRINGS_H */
#endif /* HAVE_STRING_H */

#ifdef HAVE_STDLIB_H
#include "stdlib.h"
#else
#error __FILE__ requires the stdlib.h header file.
#endif /* HAVE_STDLIB_H */

/* Try to sort out the integer mess */
#ifdef HAVE_STDINT_H
#include "stdint.h"
#else
#ifdef HAVE_INTTYPES_H
#include "inttypes.h"
#else
#ifdef WINCE
#include "winceint.h"
#else
#warning Using non-standard integer definitions. What, no stdint.h?

#ifndef _INT8_T
#define _INT8_T
typedef signed char int8_t;
#endif /* _INT8_T */

#ifndef _UINT8_T
#define _UINT8_T
typedef unsigned char uint8_t;
#endif /* _UINT8_T */

#ifndef _INT16_T
#define _INT16_T
typedef signed short int16_t;
#endif /* _INT16_T */

#ifndef _UINT16_T
#define _UINT16_T
typedef unsigned short uint16_t;
#endif /* _UINT16_T */

#ifndef _INT32_T
#define _INT32_T
typedef signed long int32_t;
#endif /* _INT32_T */

#ifndef _UINT32_T
#define _UINT32_T
typedef unsigned long uint32_t;
#endif /* _UINT32_T */

#ifndef _INT64_T
#define _INT64_T
typedef signed long long int64_t;
#endif /* _INT64_T */

#ifndef _UINT64_T
#define _UINT64_T
typedef unsigned long long uint64_t;
#endif /* _UINT64_T */

#endif /* UNDER_CE */
#endif /* HAVE_INTTYPES_H */
#endif /* HAVE_STDINT_H */

#define MU_END16(x)  ((((uint16_t)(x) & 0x00FF) << 8) \
                     | (((uint16_t)(x) & 0xFF00) >> 8))
#define MU_END32(x)  ((((uint32_t)(x) & 0x000000FF) << 24) \
                     | (((uint32_t)(x) & 0x0000FF00) <<  8) \
                     | (((uint32_t)(x) & 0x00FF0000) >>  8) \
                     | (((uint32_t)(x) & 0xFF000000) >> 24))
#define MU_END64(x)  ((((uint64_t)(x) & 0x00000000000000FFLL) << 56) \
                     | (((uint64_t)(x) & 0x000000000000FF00LL) << 40) \
                     | (((uint64_t)(x) & 0x0000000000FF0000LL) << 24) \
                     | (((uint64_t)(x) & 0x00000000FF000000LL) <<  8) \
                     | (((uint64_t)(x) & 0x000000FF00000000LL) >>  8) \
                     | (((uint64_t)(x) & 0x0000FF0000000000LL) >> 24) \
                     | (((uint64_t)(x) & 0x00FF000000000000LL) >> 40) \
                     | (((uint64_t)(x) & 0xFF00000000000000LL) >> 56))

/* define our own HTON, etc. because ANSI didn't require a 64 bit version */
#ifdef WORDS_BIGENDIAN
#define MU_HTON16(x) (x)
#define MU_HTON32(x) (x)
#define MU_HTON64(x) (x)
#define MU_NTOH16(x) (x)
#define MU_NTOH32(x) (x)
#define MU_NTOH64(x) (x)
#else
#define MU_HTON16(x)  ((((uint16_t)(x) & 0x00FF) << 8) \
                     | (((uint16_t)(x) & 0xFF00) >> 8))
#define MU_HTON32(x)  ((((uint32_t)(x) & 0x000000FF) << 24) \
                     | (((uint32_t)(x) & 0x0000FF00) <<  8) \
                     | (((uint32_t)(x) & 0x00FF0000) >>  8) \
                     | (((uint32_t)(x) & 0xFF000000) >> 24))
#define MU_HTON64(x)  ((((uint64_t)(x) & 0x00000000000000FFLL) << 56) \
                     | (((uint64_t)(x) & 0x000000000000FF00LL) << 40) \
                     | (((uint64_t)(x) & 0x0000000000FF0000LL) << 24) \
                     | (((uint64_t)(x) & 0x00000000FF000000LL) <<  8) \
                     | (((uint64_t)(x) & 0x000000FF00000000LL) >>  8) \
                     | (((uint64_t)(x) & 0x0000FF0000000000LL) >> 24) \
                     | (((uint64_t)(x) & 0x00FF000000000000LL) >> 40) \
                     | (((uint64_t)(x) & 0xFF00000000000000LL) >> 56))
#define MU_NTOH16(x)  ((((uint16_t)(x) & 0x00FF) << 8) \
                     | (((uint16_t)(x) & 0xFF00) >> 8))
#define MU_NTOH32(x)  ((((uint32_t)(x) & 0x000000FF) << 24) \
                     | (((uint32_t)(x) & 0x0000FF00) <<  8) \
                     | (((uint32_t)(x) & 0x00FF0000) >>  8) \
                     | (((uint32_t)(x) & 0xFF000000) >> 24))
#define MU_NTOH64(x)  ((((uint64_t)(x) & 0x00000000000000FFLL) << 56) \
                     | (((uint64_t)(x) & 0x000000000000FF00LL) << 40) \
                     | (((uint64_t)(x) & 0x0000000000FF0000LL) << 24) \
                     | (((uint64_t)(x) & 0x00000000FF000000LL) <<  8) \
                     | (((uint64_t)(x) & 0x000000FF00000000LL) >>  8) \
                     | (((uint64_t)(x) & 0x0000FF0000000000LL) >> 24) \
                     | (((uint64_t)(x) & 0x00FF000000000000LL) >> 40) \
                     | (((uint64_t)(x) & 0xFF00000000000000LL) >> 56))
#endif /* WORDS_BIGENDIAN */

/* Typedefs, Structs, Enums, Unions */

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

  /* Function Prototypes */
  int mu_cpp_find( char *array[], char *trial, unsigned int size );
  void mu_cp_hexprint( int fd, char *array, unsigned int size );
  void mu_cp_fhexprint( FILE *fp, char *array, unsigned int size );

  /* Global Variable Declarations */

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* _H_MUTIL */
